import win32serviceutil
import win32service
import win32event
import win32evtlogutil
import sys, os

import logging
import bumblebee
from bumblebee import Bumblebee

def find_exec_path():
    if hasattr(sys,"frozen"):
        return os.path.dirname(os.path.abspath(sys.executable))
    else:
        return os.path.abspath(os.path.join(os.path.dirname(__file__)))

EXEC_PATH = find_exec_path()
CONFIG_PATH = os.path.join(EXEC_PATH, "config", "bumblebee.ini")

class BumblebeeService(win32serviceutil.ServiceFramework):
    _svc_name_ = "Bumblebee"
    _svc_display_name_ = "Bumblebee"
    _svc_deps_ = ["EventLog"]
    
    def __init__(self, args):
        win32serviceutil.ServiceFramework.__init__(self, args)
        self.hWaitStop = win32event.CreateEvent(None, 0, 0, None)
    
    def SvcStop(self):
        self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
        win32event.SetEvent(self.hWaitStop)
        
    def SvcDoRun(self):
        import servicemanager
        
        # Write started event to event log
        win32evtlogutil.ReportEvent(self._svc_name_,
                                    servicemanager.PYS_SERVICE_STARTED,
                                    0, # category
                                    servicemanager.EVENTLOG_INFORMATION_TYPE,
                                    (self._svc_name_, ''))

        bb = None
        try:
            bumblebee.EXEC_PATH = EXEC_PATH
            bumblebee.LOGGING = 2 # make sure it's not logging to stdout.
            bb = Bumblebee(CONFIG_PATH)
            bb.start()
            logging.info("Service successfully started.")
        except:
            logging.exception("Error starting autobot.")
            win32evtlogutil.ReportEvent(self._svc_name_,
                                        servicemanager.PYS_SERVICE_STARTED,
                                        0,
                                        servicemanager.EVENTLOG_ERROR_TYPE,
                                        (self._svc_name_, ''))
            self.SvcStop()
            
        # Wait for stop event
        win32event.WaitForSingleObject(self.hWaitStop, win32event.INFINITE)
        
        # Stop bumblebee and clean up
        if bb:
            bb.halt()
            bb.join(15.)
            
            if bb.isAlive():
                logging.info("Bumblebee forced to stop.")
            else:
                logging.info("Bumblebee stopped gracefully.")
            
            logging.shutdown()
        
        # Write stopped event to event log
        win32evtlogutil.ReportEvent(self._svc_name_, 
                                    servicemanager.PYS_SERVICE_STOPPED,
                                    0,
                                    servicemanager.EVENTLOG_INFORMATION_TYPE,
                                    (self._svc_name_, ''))
                                    
if __name__ == '__main__':
    # Note that this code will not be run in the 'frozen' exe-file!!!
    win32serviceutil.HandleCommandLine(BumblebeeService)
